/****************************************
File: opdracht6.h

This file is part of Stellar

Copyright (C) 2001 David Stibbe (dstibbe@gmail.com)
                     and Gerrit Jan Jansen

Stellar is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
****************************************/

#ifndef OPDRACHT6_H
#define OPDRACHT6_H

#include <string.h>
#include "framework.h"

#define MAX_MODELS 4
#define MAX_MOONS 64
#define MAX_PLANETS 32

typedef struct modelS model;
typedef struct planetS planet_data;
typedef struct moonS moon_data;


class moon{
public:
		moon(moon_data* moon);

		void getTranslation(float *);
		void getRotation(float *);
		void rotate();
		void rotate(float rotFactor);
		float getAngle();
		float getSize();
		void getColor(float *);
		void reset();
		model* getModel();
private:
		moon_data* data;
		float angle;
};

class planet{
public:
		planet(planet_data* planet);

		void getTranslation(float *);
		void getRotation(float *);
		void rotate();
		void rotate(float rotFactor);
		float getAngle();
		float getSize();
		void getColor(float *);
		void reset();
		moon* getMoon(int n);
		int getMoonN();
		model* getModel();
private:
		planet_data* data;
		float angle;
};

typedef struct modelS{
 	int numberOfVertices;	// aantal vertices in het model
	vertex *vertices;			// alle vertices van het model
	int numberOfFaces;		// aantal faces in het model
	face *faces;				// alle faces van het model
}model;

typedef struct planetS{
	float color[3];
	float rotation[3];
	float translation[3];
	float rotation_speed;
	float size;
	int numberOfMoons;
	moon* moon_list[MAX_MOONS];
	model* shape;
	char name[16];
}planet_data;

typedef struct moonS{
	float color[3];
	float rotation[3];
	float translation[3];
	float rotation_speed;
	float size;
	model* shape;
}moon_data;


/****************************************************************************************
 *                          FUNCTIONS                                                   *
 ****************************************************************************************/

// Function name	: cPlanet_data
// Description	    : creates a new planet_data struct
// Return type		: extern void
// Argument         : all kinda data
planet_data* cPlanet_data(	float rotation[],
						    float translation[],
							float color[],
							float rotation_speed,
							float size,
							int numberOfMoons,
							moon* moon_list[],
							model* shape ,
							char* name);

// Function name	: cMoon_data
// Description	    : creates a new moon_data struct
// Return type		: extern void
// Argument         : all kinda data
moon_data* cMoon_data(	float rotation[],
						float translation[],
						float color[],
						float rotation_speed,
						float size,
						model* shape );


// Function name	: loadModel
// Description	    : loads the given shape model into memory/
// Return type		: extern void
// Argument         : int numberOfVertices
// Argument         : vertex* vertices
// Argument         : int numberOfFaces
// Argument         : face* faces
extern void loadModel(int numberOfVertices,vertex* vertices,int numberOfFaces,face* faces );

// Function name	: normalVector
// Description	    : determines the normal vector n of the plane determined by e1 and e2
// Return type		: extern void
// Argument         : float e1[]
// Argument         : float e2[]
// Argument         : float n[]
extern void normalVector(float e1[],float e2[],float n[]);

// Function name	: plotAxes
// Description	    : plots the x-y (red and green) plane and z (blue) axis
// Return type		: extern void
extern void plotAxes();

// Function name	: createMoon
// Description	    : creates a moon and adds it to the global list and returns a pointer
// Return type		: extern void
// Argument         : moon_data* moon
extern moon* createMoon(moon_data* moonData);

// Function name	: createPlanet
// Description	    : creates a planet and his moons and adds it to the global list.
// Return type		: extern void
// Argument         : planet_data* planet
extern void createPlanet(planet_data* planet);

// Function name	: createUniverse
// Description	    : defines/creates all the planets and moons
// Return type		: extern void
extern void createUniverse();

// Function name	: moveUniverse
// Description	    : moves every planet/moon according to their rotation and speed
// Return type		: extern void
extern void moveUniverse();

// Function name	: drawPlanet
// Description	    : draw planet number 'planet_number'  and his moons
// Return type		: extern void
// Argument         : int planet_number
// NOTE				: make sure you saved the current matrix before loading this function.
extern void drawPlanet(int planet_number);

// Function name	: drawUniverse
// Description	    : draws the complete universe
// Return type		: extern void
extern void drawUniverse();

// Function name	: resetUniverse
// Description	    : reset all the planets/moons to their starting positions
// Return type		: extern void
extern void resetUniverse();


// Function name	: drawModel
// Description	    : draws the polygons of the given model
// Return type		: extern void
// Argument         : p->getModel(
extern void drawPolygonModel(model* m);


// Function name	: fillMf3
// Description	    : fills a 3d dimensional float array with x,y &z
// Return type		: extern void
// Argument         : float* M
// Argument         : float x
// Argument         : float y
// Argument         : float z
extern void fillMf3(float* M,float x,float y,float z);


// Function name	: zoom
// Description	    : multiplies the current zoom with factor
// Return type		: void
// Argument         : float factor
void zoom(float factor);

// Function name	: rotationNormal
// Description	    : determines the normal needed to rotate ,
//                    given a translation
// Return type		: void
// Argument         : float trans[]
// Argument         : float* rotation
void rotationNormal(float trans[],float* rotation);

// Function name	: normalVector2
// Description	    : an adaptation of normalVector, this does the same,
//                    except for scaling the vector to 1
// Return type		: void
// Argument         : float e1[]
// Argument         : float e2[]
// Argument         : float n[]
void normalVector2(float e1[],float e2[],float n[]);


// Function name	: setScaleFactor
// Description	    : sets the scaling factor
// Return type		: void
// Argument         : float sFactor
void setScaleFactor(float sFactor);


// Function name	: setTransFactor
// Description	    : sets the translation factor
// Return type		: void
// Argument         : float tFactor
void setTransFactor(float tFactor);

// Function name	: setRotFactor
// Description	    : sets the rotation factor
// Return type		: void
// Argument         : float rFactor
void setRotFactor(float rFactor);

#endif
